/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bs.persistencia;

import com.bs.util.TelaErro;
import java.io.Serializable;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PreDestroy;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 * Componente responsável por manter a session factory durante a execução da
 * aplicação.
 *
 * @author José Adailton dos Santos.
 */
public class HelperHibernate implements Serializable {

    private static SessionFactory factory;
    private static String usuario;
    private static String senha;
    private static String arquivoConf = "hibernate.cfg.xml";

    public static void setArquivoConf(String string) {
        arquivoConf = string;
    }

    public static void setSenha(String senha) {
        HelperHibernate.senha = senha;
    }
    private Session sessaoAtual;
    private Transaction transacaoAtual;

    @PreDestroy
    public void destroiFactory() {
        factory.close();
        factory = null;
    }

    public static void abrir(String usuario, String senha) {
        try {
            HelperHibernate.usuario = usuario;
            if (usuario.equals("configurar")) {
                return;
            }
//            String cnn ="jdbc:firebirdsql://localhost:3050/" + System.getProperty("user.dir") + "/base/base";
            AnnotationConfiguration anConf = new AnnotationConfiguration().configure(arquivoConf);
//            anConf.setProperty("hibernate.connection.url", cnn);
            anConf.setProperty("hibernate.connection.username", usuario);
            anConf.setProperty("hibernate.connection.password", senha);

            factory = anConf.buildSessionFactory();
        } catch (HibernateException ex) {
            TelaErro.exibeErro(ex);
        } catch (Exception ex) {
            TelaErro.exibeErro(ex);
            System.exit(0);
        }

    }

    public Session getSessaoAtual() {
        return sessaoAtual;
    }

    public void setSessaoAtual(Session sessaoAtual) {
        this.sessaoAtual = sessaoAtual;
    }

    public void comit() {
        transacaoAtual.commit();
    }

    public void rollback() {
        transacaoAtual.rollback();
    }

    public void begin() {
        transacaoAtual.begin();
    }

    public static SessionFactory getSessionFactory() {
        if (factory == null) {
            HelperHibernate.abrir("", "");
        }
        return HelperHibernate.factory;
    }

    public static boolean sessaoAberta() {
        return factory != null;
    }

    public void Bloquear() {
        if (factory != null) {
            factory.close();
        }
        factory = null;
    }

    public SessionFactory getFactory() {
        if (factory == null) {
            abrir("adailton", "leticia");
        }
        return HelperHibernate.factory;
    }

    public void setFactory(SessionFactory factory) {
        HelperHibernate.factory = factory;
    }

    public Session openSession() {
        if (factory == null) {
            Bloquear();
        }
        return getFactory().openSession();
    }

    public Session getCurrentSession() {
        if (factory == null) {
            Bloquear();
        }
        try {
            return getFactory().getCurrentSession();
        } catch (Exception ex) {
            return openSession();
        }
    }

    public static String getUsuario() {
        return usuario;
    }

    public static void setUsuario(String usuario) {
        HelperHibernate.usuario = usuario;
    }

    public Collection getCollection(String query) {
        Query q = getCurrentSession().createQuery(query);
        Collection ret = q.list();
        return ret;
    }

    public Collection getCollection(Class classe, String campo,
            String valor) {
        Criteria crit = getCurrentSession().createCriteria(classe);
        Collection ret = crit.add(Restrictions.ilike(campo, "%" + valor + "%")).list();
        return ret;
    }

    public Collection getCollection(Class classe, String campo,
            Object valor) {
        Criteria crit = getCurrentSession().createCriteria(classe);
        Collection ret = crit.add(Restrictions.eq(campo, valor)).list();
        return ret;
    }

    public Collection getCollection(Class classe, Criterion restricao, int limiteDeRegistros) {
        Criteria crit = getCurrentSession().createCriteria(classe);
        crit.setMaxResults(limiteDeRegistros);
        Collection ret = crit.add(restricao).list();

        return ret;
    }

    public Collection getCollection(Class classe, Criterion restricao) {

        Criteria crit = getCurrentSession().createCriteria(classe);
        Collection ret = crit.add(restricao).list();

        return ret;
    }

    public Collection getCollection(Class classe, Criterion restricao, String ordenarPor) {

        Criteria crit = getCurrentSession().createCriteria(classe);
        crit.addOrder(Order.asc(ordenarPor));
        Collection ret = crit.add(restricao).list();

        return ret;
    }

    public Collection getCollection(Class classe, Criterion restricao, Order ordenarPor) {

        Criteria crit = getCurrentSession().createCriteria(classe);
        crit.addOrder(ordenarPor);
        Collection ret = crit.add(restricao).list();

        return ret;
    }

    public Collection getCollection(Class objeto) {

        Collection ret = getCurrentSession().createCriteria(objeto).list();

        return ret;
    }

    public Object load(Class classe, Serializable valor) {

        Object ret = getCurrentSession().get(classe, valor);


        return ret;
    }

    public Collection<Object> loadFull(Class classe) {

        Collection<Object> ret = getCurrentSession().createCriteria(classe).list();
        return ret;
    }

    public void load(Object classe, Serializable valor) {

        getCurrentSession().load(classe, valor);


    }

    public void persist(Object classe) {
        getCurrentSession().persist(classe);
    }

    public void merge(Object classe) {
        getCurrentSession().merge(classe);
    }

    public Serializable save(Object classe) {
        try {
            Serializable id;
            id = getCurrentSession().save(classe);
            return id;
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
        return 0;
    }

    public void update(Object classe) {
        getCurrentSession().update(classe);
    }

    public void delete(Object classe) {
        getCurrentSession().delete(classe);
    }

    public ResultSet executeFuncao(String funcao) {
        try {
            ResultSet ret;
            CallableStatement pr = getCurrentSession().connection().prepareCall(funcao);
            ret = pr.executeQuery();
            return ret;
        } catch (SQLException ex) {
            Logger.getLogger(HelperHibernate.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}
